import type { Fix, KeyAndVal } from "./utils";

export type RenderParams = {
  comp: VueComponent;
  params: KeyAndVal;
}[];

/** 基础组件接口 */
export interface BaseComponent<D = KeyAndVal, P = KeyAndVal> {
  getData(): D; // 获取组件数据
  setData(data: D): void; // 设置组件数据
  getProps(): P; // 获取组件参数
  setProps(props: P): void; // 设置组件参数
}

/**生命周期 */
export interface Lifecycle<T = unknown> {
  setup(instance: Fix<T, Function>): void; // 创建时
  onBeforeMount(instance: Fix<T, Function>): void; // dom挂载前
  onMounted(instance: Fix<T, Function>): void; // 挂载完成
  onBeforeUnMount(instance: Fix<T, Function>): void; // 销毁前
  onUnmounted(instance: Fix<T, Function>): void; // 销毁后
}

/**页面的基础类 */
export abstract class Component<D = unknown, P = unknown, L = unknown> implements BaseComponent<D, P>, Lifecycle<L> {
  private data: D;
  private props: P;
  constructor(data: D = {} as D, props: P = {} as P) {
    this.data = data;
    this.props = props;
  }
  getData(): D {
    return this.data;
  }
  setData(data: D): void {
    console.log("setData 该方法应该被继承类对应的Vue文件覆盖");
  }
  getProps(): P {
    return this.props;
  }
  setProps(props: P): void {}

  setup(instance: Fix<L, Function>): void {
    throw new Error("Method not implemented.");
  }
  onBeforeMount(instance: Fix<L, Function>): void {
    throw new Error("Method not implemented.");
  }
  onMounted(instance: Fix<L, Function>): void {
    throw new Error("Method not implemented.");
  }
  onBeforeUnMount(instance: Fix<L, Function>): void {
    throw new Error("Method not implemented.");
  }
  onUnmounted(instance: Fix<L, Function>): void {
    throw new Error("Method not implemented.");
  }
}

export abstract class VueComponent<D = unknown, P = unknown, L = unknown> extends Component<D, P, L> {
  private field: string = "";
  private dataSource: any;
  abstract getComponentName(): string;
  getField() {
    return this.field;
  }
  setField(field: string) {
    this.field = field;
  }
  getDataSource() {
    return this.dataSource;
  }
  setDataSource(dataSource: any) {
    this.dataSource = dataSource;
    return this;
  }
}

export type WidthType = `${number}px` | `${number}vw` | `${number}%`;
export type HeightType = `${number}px` | `${number}vh` | `${number}%`;
